import banco.aplicacao;
import banco.transacao;
import java.net.URL;
import java.sql.*;

public class ServidorDOA {
        /** Tipos de Transacoes */
    private final int POUPANCA = 0;
    private final int FUNDO_ACOES = 1;
    private final int RENDA_FIXA = 2;
    private final int SAQUE = 3;
    private final int TRANSF_DEBITO = 4;
    private final int TRANSF_CREDITO = 5;    
    
    private String driver = "sun.jdbc.odbc.JdbcOdbcDriver";
    private String URL="jdbc:odbc:myDSN"; 
    private String database="banco.mdb";
    private java.sql.Connection con = null;
    java.text.SimpleDateFormat data = new java.text.SimpleDateFormat("dd/MM/yyyy");
    java.text.SimpleDateFormat dataDouble = new java.text.SimpleDateFormat("ddMMyyyy");
    
    static Connection connection;

    public ServidorDOA() {
        String accessDBURLPrefix = "jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=";
        String accessDBURLSuffix = ";DriverID=22;READONLY=false}";

        try {
            Class.forName(driver);

            URL = accessDBURLPrefix + database + accessDBURLSuffix;

            System.out.println(URL);

            con = DriverManager.getConnection(URL, "", "");

            System.out.println("Conectado ao banco de dados! " + data.format(new java.util.Date()).toString());

//            Statement stmt = con.createStatement();
//
//            System.out.println("Stmt criado!");
//            
//            String statement = "SELECT * FROM Conta";
//            ResultSet rs = stmt.executeQuery(statement);
//            
//            System.out.println(statement);
//                                   
//            while (rs.next()){
//                String aux = rs.getString("Nome");
//                System.out.println(aux);
//                double num = rs.getDouble("saldo");
//                System.out.println(num);
//            }

//            double teste = getSaldoConta(1);
//            System.out.println("Saldo da conta 1 = " + teste);
//            teste = getSaldoConta(2);
//            System.out.println("Saldo da conta 2 = " + teste);
//            System.out.println("============================");
//            System.out.println("TRANSFERENCIA");
//            transferencia(2, 1, 500);
//            teste = getSaldoConta(1);
//            System.out.println("Saldo da conta 1 = " + teste);
//            teste = getSaldoConta(2);
//            System.out.println("Saldo da conta 2 = " + teste);
//            System.out.println("============================");
//            System.out.println("SAQUE");
//            saque(2, 321);
//            System.out.println("FIM");

        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
        }

    }

    double getSaldoConta(int conta) {

        try {
            Statement stmt = con.createStatement();

            String statement = "SELECT * FROM Conta WHERE Codigo = " + conta;
            ResultSet rs = stmt.executeQuery(statement);

            //System.out.println(statement);                        
            while (rs.next()) {
                if (rs.getInt("Codigo") == conta) {
                    System.out.println("Buscando saldo da conta " + conta + ".");
                    return rs.getInt("saldo");
                }
            }
            return -99;

        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return -99;
        }

    }

    boolean transferencia(int contaOrigem, int contaDestino, double valorDaTransferencia) {
        double saldoContaOrigem = 0, saldoContaDestino = 0;
        try {
            Statement stmt = con.createStatement();

            //Verificar se conta de origem existe
            String statement = "SELECT * FROM Conta WHERE Codigo = " + contaOrigem;
            ResultSet rs = stmt.executeQuery(statement);
            //System.out.println(statement);

            while (rs.next()) {
                if (rs.getInt("Codigo") == contaOrigem) {
                    saldoContaOrigem = rs.getDouble("saldo");
                    System.out.println("Saldo da conta de origem " + contaOrigem + " = " + saldoContaOrigem);
                } else {
                    System.err.println("Conta de Origem inexistente.");
                    return false;
                }
            }

            //verificar se existe saldo suficiente na conta de origem
            if (saldoContaOrigem > valorDaTransferencia) {
                saldoContaOrigem = saldoContaOrigem - valorDaTransferencia;
                System.out.println("Saldo suficiente para operação.");
            } else {
                System.err.println("Saldo insuficiente para operação.");
                return false;
            }

            //Verificar se conta de destino existe
            statement = "SELECT * FROM Conta WHERE Codigo = " + contaDestino;
            rs = stmt.executeQuery(statement);
            //System.out.println(statement);

            while (rs.next()) {
                if (rs.getInt("Codigo") == contaDestino) {
                    saldoContaDestino = rs.getDouble("saldo");
                    System.out.println("Saldo da conta de destino " + contaDestino + " = " + saldoContaDestino);
                    saldoContaDestino = saldoContaDestino + valorDaTransferencia;
                    System.err.println("Transferindo R$" + valorDaTransferencia + "da conta " + contaOrigem + "para conta " + contaDestino);
                } else {
                    System.err.println("Conta de Destino inexistente.");
                    return false;
                }
            }
            /* Salvar novo saldo da conta de origem  */
            statement = "UPDATE conta SET saldo = " + saldoContaOrigem + " WHERE Codigo = " + contaOrigem;
            stmt.execute(statement);
            //System.out.println(statement);
            System.out.println("Novo saldo da conta " + contaOrigem + " R$" + saldoContaOrigem);

            //Escrever no historico da conta de origem
            statement = "INSERT INTO Historico (conta, transacao, valor, data) VALUES ( " + contaOrigem + "," + TRANSF_DEBITO + " , " + valorDaTransferencia + ", '" + data.format(new java.util.Date()).toString() + "')";
            stmt.execute(statement);

            /* Salvar novo saldo da conta de destino */
            statement = "UPDATE conta SET saldo = " + saldoContaDestino + " WHERE Codigo = " + contaDestino;
            stmt.execute(statement);
            //System.out.println(statement);
            System.out.println("Novo saldo da conta " + contaDestino + " R$" + saldoContaDestino);

            //Escrever no historico da conta de destino
            statement = "INSERT INTO Historico (conta, transacao, valor, data) VALUES ( " + contaDestino + "," + TRANSF_CREDITO + ", " + valorDaTransferencia + ", '" + data.format(new java.util.Date()).toString() + "')";
            stmt.execute(statement);

            return true;

        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return false;
        }
    }

    boolean saque(int conta, double valorSaque) {
        double saldoConta = 0;
        try {
            Statement stmt = con.createStatement();

            //Verificar se conta de origem existe
            String statement = "SELECT * FROM Conta WHERE Codigo = " + conta;
            ResultSet rs = stmt.executeQuery(statement);
            //System.out.println(statement);

            while (rs.next()) {
                if (rs.getInt("Codigo") == conta) {
                    saldoConta = rs.getDouble("saldo");
                    System.out.println("Saldo da conta " + conta + " R$" + saldoConta);
                } else {
                    System.err.println("Conta inexistente.");
                    return false;
                }
            }

            //verificar se existe saldo suficiente na conta de origem
            if (saldoConta > valorSaque) {
                saldoConta = saldoConta - valorSaque;
                System.out.println("Saldo suficiente para operação.");
            } else {
                System.err.println("Saldo insuficiente para operação.");
                return false;
            }

            /* Salvar novo saldo da conta de destino */
            statement = "UPDATE conta SET saldo = " + saldoConta + " WHERE Codigo = " + conta;
            stmt.execute(statement);
            System.out.println("Novo saldo após retirada da conta " + conta + " R$" + saldoConta);
            //System.out.println(statement);
            statement = "INSERT INTO Historico (conta, transacao, valor, data) VALUES ( " + conta + "," + SAQUE + ", " + valorSaque + ", '" + data.format(new java.util.Date()).toString() + "')";
            stmt.execute(statement);

            return true;

        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return false;
        }
    }

    public transacao[] extrato(int conta) {
        transacao[] historico = null;
        int num_historico = 0;

        try {
            //Statement st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
            String statement = "SELECT * FROM Historico WHERE Conta = " + conta + " ORDER BY Data";
            Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

            //Verificar se conta de origem existe

            ResultSet rs = stmt.executeQuery(statement);
            //System.out.println(statement);

            while (rs.next()) {
                num_historico = num_historico + 1;
            }

            //Cria um array de historico com numero.
            System.out.println("tamanho do historico - " + num_historico);

            rs.first();

            if (num_historico == 0) {
                return historico;
            } else {
                historico = new transacao[num_historico];
                transacao[] hist = new transacao[num_historico - 1];

                int i = 0;
                //System.out.println("-------- antes dentro extrato --------");
                while (rs.next()) {
                    String dat = rs.getDate("Data").toString();
                    //System.out.println("data - " + dataDouble.format(Date.valueOf(dat)));
                    int dt = Integer.valueOf(dataDouble.format(Date.valueOf(dat)));
                    //historico[i].quantia = rs.getDouble("Valor");
                    //data.format(new java.util.Date()).toString());
                    transacao tr = new transacao();
                    tr.data = dt;
                    tr.quantia = rs.getDouble("Valor");

                    switch (rs.getInt("transacao")) {
                        case POUPANCA:
                            tr.descricao = "Poupanca";
                            break;
                        case FUNDO_ACOES:
                            tr.descricao = "Fundo Acoes";
                            break;
                        case RENDA_FIXA:
                            tr.descricao = "Renda Fixa";
                            break;
                        case SAQUE:
                            tr.descricao = "Saque";
                            break;
                        case TRANSF_DEBITO:
                            tr.descricao = "Transf. debito";
                            break;
                        case TRANSF_CREDITO:
                            tr.descricao = "Transf. credito";
                    }
                    //historico[i] = new transacao(dt, rs.getString("Transacao"), rs.getDouble("Valor"));
                    historico[i] = tr;
                    hist[i] = tr;
                    i++;
                }
                //System.out.println("-------- depois dentro extrato --------");
                //System.out.println("Inicio do FOR");
//                for (int j = 0; j < hist.length; j++) {
//                    System.out.println(hist[j].descricao);                    
//                }
                //System.out.println("Fim do FOR");
                
                return hist;
            }
        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return historico;
        }
    }

    public boolean investimento(int conta, aplicacao apl, double valor) {
        int opcaoInvestimento = banco.aplicacao.poupanca.value();
        double saldoConta = 0;
        
        if (opcaoInvestimento < 0 || opcaoInvestimento > 2) {
            System.err.println("Erro paramentro em investimento(): valor de banco.aplicacao nao e valido.");
            return false;
        }

        try {
            Statement stmt = con.createStatement();

            //Verificar se conta de origem existe
            String statement = "SELECT * FROM Conta WHERE Codigo = " + conta;
            ResultSet rs = stmt.executeQuery(statement);

            while (rs.next()) {
                if (rs.getInt("Codigo") == conta) {
                    saldoConta = rs.getDouble("saldo");
                    System.out.println("Saldo da conta " + conta + " R$" + saldoConta);
                } else {
                    System.err.println("Conta inexistente.");
                    return false;
                }
            }

            if (saldoConta < valor) {
                /* se nao for, retorna erro de saldo_insuf */
                System.err.println("Conta inexistente.");
                return false;
            } else {
                double aux = saldoConta - valor;
                stmt.execute("UPDATE Conta SET Saldo = " + aux + " WHERE Codigo = " + conta);
                //stmt.execute ("INSERT INTO aplicacao VALUES ("+ conta +","+ opcaoInvestimento +","+ valor +")");                
                stmt.execute ("INSERT INTO historico (conta, transacao, valor, data) " +
                        "VALUES ("+ conta +","+ opcaoInvestimento +","+ valor +", '" + data.format(new java.util.Date()).toString() + "' )");
                
                System.out.println("Investimento conta " + conta + " do tipo " + opcaoInvestimento);
                return true;

            //statement.execute ("INSERT INTO aplicacao VALUES ("+ conta +","+ opcaoInvestimento +","+ valor +")");                
//                stmt.execute ("INSERT INTO historico (numero_conta, tipo_aplicacao, valor) " +
//                        "VALUES ("+ conta +","+ opcaoInvestimento +","+ valor +")");                
            }

        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return false;
        }

    }
}
